<article id="wikiArticle">
<div class="warning"><strong>非标准的。不要使用！</strong><br/>
generator推导式是非标准的，而且它不太可能会被添加到ECMAScript。考虑到将来，请使用 <a href="Reference/Statements/function*" title="function* 这种声明方式(function关键字后跟一个星号）会定义一个生成器函数 (generator function)，它返回一个  Generator  对象。">generator</a>。
<p> </p>
</div>
<p></p><p></p>
<p>生成器推导语法是一种JavaScript表达式，它允许您基于现有的可迭代对象快速组合新的生成器函数。</p>
<p>许多编程语言中都存在推导。</p>
<p>看下面，原来Generator推导式语法在SpiderMonkey的不同之处，它是基于对ECMAScript4的提议。</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)
</code></pre>
<h2 id="描述">描述</h2>
<p>在Generator推导式中，这两种构成方式都是允许的：</p>
<ul>
<li><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象（包括 Array，Map，Set，String，TypedArray，arguments 对象等等）上创建一个迭代循环，调用自定义迭代钩子，并为每个不同属性的值执行语句"><code>for...of</code></a> </li>
<li><a href="Reference/Statements/if...else" title="当指定条件为真，if 语句会执行一段语句。如果条件为假，则执行另一段语句。"><code>if</code></a></li>
</ul>
<p>for-of迭代器是构成的第一个部分。当由多重部分构成时，后面for-of和if构成方式都是被允许的。</p>
<h2 id="示例">示例</h2>
<h3 id="单个构成部分的_generator推导式：">单个构成部分的 generator推导式：</h3>
<pre><code class="language-js">(for (i of [ 1, 2, 3 ]) i*i );
// generator function which yields 1, 4, and 9

[...(for (i of [ 1, 2, 3 ]) i*i )];
// [1, 4, 9]

var abc = [ "A", "B", "C" ];
(for (letters of abc) letters.toLowerCase());
// generator function which yields "a", "b", and "c"

</code></pre>
<h3 id="有if伴随的多重构成的gennerator推导式：">有if伴随的多重构成的gennerator推导式：</h3>
<pre><code  class="language-javascript">var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];

(for (year of years) if (year &gt; 2000) year);
// generator function which yields 2006, 2010, and 2014

(for (year of years) if (year &gt; 2000) if(year &lt; 2010) year);
// generator function which yields 2006, the same as below:

(for (year of years) if (year &gt; 2000 &amp;&amp; year &lt; 2010) year);
// generator function which yields 2006
</code></pre>
<h3 id="Generator推导式与Generator函数对比">Generator推导式与Generator函数对比</h3>
<p>用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。</p>
<p>Example 1: 仅是 generator.</p>
<pre><code  class="language-javascript">var numbers = [ 1, 2, 3 ];

// Generator 函数
(function*() {
  for (let i of numbers) {
    yield i * i;
  }
})()

// Generator 推导式
(for (i of numbers) i*i );

// 结果: 两者都得到 yields [ 1, 4, 9 ]
</code></pre>
<p>Example 2: 在 generator 中用if.</p>
<pre><code  class="language-javascript">var numbers = [ 1, 2, 3 ];

// Generator 函数
(function*() {
  for (let i of numbers) {
    if (i &lt; 3) {
      yield i * 1;
    }
  }
})()

// Generator 推导式
(for (i of numbers) if (i &lt; 3) i);

// 结果: 两者都得到 yields [ 1, 2 ]</code></pre>
<h2 id="规范">规范</h2>
<p>Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.</p>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p></p><div class="blockIndicator warning"><strong><a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">We're converting our compatibility data into a machine-readable JSON format</a></strong>.
            This compatibility table still uses the old format,
            because we haven't yet converted the data it contains.
            <strong><a class="new" href="/zh-CN/docs/MDN/Contribute/Structures/Compatibility_tables" rel="nofollow">Find out how you can help!</a></strong></div>
<div class="htab">
<a id="AutoCompatibilityTable" name="AutoCompatibilityTable"></a>
<ul>
<li class="selected"><a>Desktop</a></li>
<li><a>Mobile</a></li>
</ul>
</div><p></p>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: #f00;">未实现</span></td>
<td><a href="/en-US/Firefox/Releases/30" title="Released on 2014-06-10.">30</a> (30)</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Chrome for Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td>30.0 (30)</td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
<td><span style="color: #f00;">未实现</span></td>
</tr>
</tbody>
</table>
</div>
<h3 id="SpiderMonkey的具体实现笔记">SpiderMonkey的具体实现笔记</h3>
<ul>
<li><a href="Reference/Statements/let" title="let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是，var声明的变量只能是全局或者整个函数块的。"><code>let</code></a> 作为标识符，因为let当前仅可用于JS版本1.7和XUL脚本标记.</li>
<li>目前还不支持解构 (<a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=980828" rel="noopener" title="Generator and array comprehensions should support destructuring binding">bug 980828</a>).</li>
</ul>
<h3 id="与旧的JS1.7_JS1.8理解的区别">与旧的JS1.7 / JS1.8理解的区别</h3>
<ul>
<li>ES2016 的解析为每个“for”节点创建一个范围，而不是作为一个整体的理解。
  <ul>
<li>Old: <code>[...(()=&gt;x for (x of [0, 1, 2]))][1]() // 2</code></li>
<li>New: <code>[...(for (x of [0, 1, 2]) ()=&gt;x)][1]() // 1, 每个迭代都会创建一个新的x的绑定事件。</code></li>
</ul>
</li>
<li> ES2016的解析以“for”而不是赋值表达式开头。
  <ul>
<li>Old: <code>(i * 2 for (i of numbers))</code></li>
<li>New: <code>(for (i of numbers) <code>i * 2</code>)</code></li>
</ul>
</li>
<li>ES2016 解析可以有多个if和for组件。</li>
<li>ES2016 解析仅这种方式工作<code><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象（包括 Array，Map，Set，String，TypedArray，arguments 对象等等）上创建一个迭代循环，调用自定义迭代钩子，并为每个不同属性的值执行语句"><code>for...of</code></a></code> 而不是<code><a href="Reference/Statements/for...in" title="for...in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性，语句都会被执行。"><code>for...in</code></a></code> 的方式迭代。</li>
</ul>
<h2 id="相关链接">相关链接</h2>
<ul>
<li><a href="Reference/Statements/for...of" title="for...of语句在可迭代对象（包括 Array，Map，Set，String，TypedArray，arguments 对象等等）上创建一个迭代循环，调用自定义迭代钩子，并为每个不同属性的值执行语句"><code>for...of</code></a></li>
<li><a href="Reference/Operators/Array_comprehensions" title="数组推导式是一种 JavaScript 表达式语法，使用它，你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它！"><code>Array comprehensions</code></a></li>
</ul>
</article>